0993. 二叉树的堂兄弟节点【简单】
1. 📝 题目描述
在二叉树中,根节点位于深度 0 处,每个深度为 k 的节点的子节点位于深度 k+1 处。
如果二叉树的两个节点深度相同,但父节点不同,则它们是一对堂兄弟节点。
我们给出了具有唯一值的二叉树的根节点 root,以及树中两个不同节点的值 x 和 y。
只有与值 x 和 y 对应的节点是堂兄弟节点时,才返回 true。否则,返回 false。
示例 1:

txt
输入:root = [1, 2, 3, 4], x = 4, y = 3
输出:false1
2
2
示例 2:

txt
输入:root = [1, 2, 3, null, 4, null, 5], x = 5, y = 4
输出:true1
2
2
示例 3:

txt
输入:root = [1, 2, 3, null, 4], x = 2, y = 3
输出:false1
2
2
提示:
- 二叉树的节点数介于
2到100之间。 - 每个节点的值都是唯一的、范围为
1到100的整数。
2. 🫧 评价
| 方面 | s.1 | s.2 |
|---|---|---|
| 核心思想 | 纯层序遍历 + 兄弟检查 | BFS + 显式记录 |
| 数据存储 | 只存 node | 存(node,parent,depth) |
| 兄弟判断 | 遍历时实时判断 | 最后比较 parent |
| 代码复杂度 | 逻辑稍复杂但优化 | 更直观简单 |
| 空间 | 稍小 | 稍大(存父节点) |
3. 🎯 s.1 - 层序遍历 + 兄弟检测
js
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} x
* @param {number} y
* @return {boolean}
*/
var isCousins = function (root, x, y) {
if (!root) return false
const queue = [root]
while (queue.length) {
const size = queue.length // 当前层的节点数
let foundX = false
let foundY = false
// 遍历当前层
for (let i = 0; i < size; i++) {
const node = queue.shift()
// 同父节点的两个孩子为 x 和 y,则是兄弟,非堂兄弟
if (node.left && node.right) {
const lv = node.left.val
const rv = node.right.val
if ((lv === x && rv === y) || (lv === y && rv === x)) {
return false
}
}
if (node.left) {
if (node.left.val === x) foundX = true
if (node.left.val === y) foundY = true
queue.push(node.left)
}
if (node.right) {
if (node.right.val === x) foundX = true
if (node.right.val === y) foundY = true
queue.push(node.right)
}
}
if (foundX && foundY) return true
if (foundX || foundY) return false // 仅在同一层出现一个,深度不同
}
return false
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
- 时间复杂度:
,其中 为节点数 - 空间复杂度:
,用于层序遍历的队列
算法思路:
- 层序遍历按层扫描节点,记录本层是否出现
x与y,若仅出现一个则不是堂兄弟(深度不同)。 - 同时检查同一父节点的两个孩子是否为
x与y,若是则为兄弟节点,返回false。 - 若在同一层同时出现且非兄弟,则为堂兄弟,返回
true。
4. 🎯 s.2 - BFS + 显式记录
js
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} x
* @param {number} y
* @return {boolean}
*/
var isCousins = function (root, x, y) {
// 使用 BFS 找到 x 和 y 的深度和父节点
const queue = [[root, null, 0]] // [节点, 父节点, 深度]
let xInfo = null
let yInfo = null
while (queue.length > 0) {
const [node, parent, depth] = queue.shift()
if (node.val === x) {
xInfo = { parent, depth }
}
if (node.val === y) {
yInfo = { parent, depth }
}
// 如果已经找到两个节点,可以提前退出
if (xInfo && yInfo) {
break
}
// 继续遍历
if (node.left) {
queue.push([node.left, node, depth + 1])
}
if (node.right) {
queue.push([node.right, node, depth + 1])
}
}
// 堂兄弟条件:深度相同且父节点不同
return (
xInfo &&
yInfo &&
xInfo.depth === yInfo.depth &&
xInfo.parent !== yInfo.parent
)
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
- 时间复杂度:
,单次 BFS 遍历所有节点 - 空间复杂度:
,队列与父节点/深度的记录
算法思路:
- 使用 BFS 层序遍历,同时显式记录每个节点的父节点
parent与深度depth - 找到值为
x与y的节点后,判断depth[x] == depth[y]且parent[x] !== parent[y] - 若满足则为堂兄弟返回
true,遍历结束未满足则返回false